서브 쿼리

개요

sql문 안에 들어간 작은 sql문을 서브쿼리라고 한다.

사용 방식

사용되는 절

서브 쿼리가 들어가는 것이 가능한 절이 몇 개 있는데, 막상 보면 엄청 당연하게 느껴진다.

분류

사용법에 있어서 엄청 어렵거나 한 것은 없는데, 시험에 나올 수도 있을 개념들은 미리 보자.

SELECT A.ADSTRD_CD
     , B.ADSTRD_NM
     , A.STD_YM
     , A.POPLTN_SE_CD
     , A.AGRDE_SE_CD
     , A.POPLTN_CNT
  FROM TB_POPLTN A
     , TB_ADSTRD B
 WHERE A.STD_YM = '202010'
   AND A.POPLTN_SE_CD = 'T'
   AND (A.AGRDE_SE_CD, A.POPLTN_CNT) IN
                                       (
                                         SELECT K.AGRDE_SE_CD
                                              , MAX(K.POPLTN_CNT) AS POPLTN_CNT
                                           FROM TB_POPLTN K
                                          WHERE K.STD_YM = '202010' 
                                            AND K.POPLTN_SE_CD = 'T'
                                          GROUP BY K.AGRDE_SE_CD
                                       )
   AND A.ADSTRD_CD = B.ADSTRD_CD
 ORDER BY A.AGRDE_SE_CD
;

이것이 다중 컬럼 서브 쿼리 방식이다.
두 가지 컬럼을 select하고 조건절에서도 두가지 컬럼을 비교한다.

EXISTS


SELECT A.SUBWAY_STATN_NO
     , A.LN_NM
     , A.STATN_NM
  FROM TB_SUBWAY_STATN A
 WHERE EXISTS ( SELECT 1
                  FROM TB_SUBWAY_STATN_TK_GFF K
                 WHERE K.SUBWAY_STATN_NO = A.SUBWAY_STATN_NO
                   AND K.STD_YM = '202010'
                   AND TK_GFF_CNT >= 250000
              )
ORDER BY A.SUBWAY_STATN_NO

exists 문법도 존재한다.
이것은 연관 서브쿼리를 활용할 때 해당 조건에 맞는 데이터들만 뽑을 수 있도록 해준다.
여기에서 1은 단순하게 있다는 값만 뽑기 위해 세팅한 값에 불과하다.
비연관 서브쿼리에도 할 수 있기는 한데, 그건 사실 의미가 없다.

이때 주의할 게 있다.
메인쿼리와 서브 쿼리 간 실행 순서에 대한 것이다.
exists문을 보면 알겠지만 현재 서브쿼리의 조건을 검사하기 위해서는 메인 쿼리에 각 행에 대해 연산이 돼야 한다.
즉, 메인 쿼리 각 행마다 해당 서브 쿼리가 작동한다는 것이다;;
from 절에 있을 때는 한번만 실행되지만 이렇게 연관서브쿼리, select절에 들어가는 서브쿼리는 다중으로 실행되기에 성능에 영향을 미칠 수 있다.

서브 쿼리는 쿼리를 작성하는데 있어서는 순서가 딱딱 나오니까 직관적일 수 있다.
그러나 불필요한 연산을 야기하는 경우가 많기에 항상 더 최적화할 방법은 고민해봐야 한다.
다만, 인라인 뷰를 활용할 때는 불필요하게 불러오는 행을 줄여서 성능이 향사되는 경우도 존재하니 확인해보자.

결국 서브쿼리는 나온 결과 값을 어떻게 활용해먹냐 정도의 머리를 굴려야 하고, 그 이상의 어려운 내용은 사실 없다.
그래서 지금 디비 곱창난 마당에 실습 없이 넘어가려고 한다..

참고